from rest_framework import serializers
from rest_framework.exceptions import ValidationError
from . import models
from django.conf import settings

class OrderSerializer(serializers.ModelSerializer):
    course = serializers.PrimaryKeyRelatedField(queryset=models.Course.objects.all(), write_only=True, many=True)

    class Meta:
        model = models.Order
        fields = ['total_amount', 'subject', 'pay_type', 'course']
        extra_kwargs = {
            'total_amount': {'required': True},
            'pay_type': {'required': True},
        }

    def _check_price(self, attrs):
        course_list = attrs.get('course')
        sum_price = 0
        for course in course_list:
            sum_price += course.price
        if sum_price != attrs.get('total_amount'):
            raise ValidationError('价格不合法')
        return sum_price

    def _get_out_trade_no(self):
        import uuid
        return str(uuid.uuid4()).replace('-', '')

    def _get_user(self):
        request = self.context.get('request')
        return request.user

    def _get_pay_url(self, sum_price, out_trade_no, subject):
        from luffyapi.libs.al_pay import alipay, gateway
        order_string = alipay.api_alipay_trade_page_pay(
            out_trade_no=out_trade_no,
            total_amount=float(sum_price),
            subject=subject,
            return_url=settings.RETURN_URL,  # get回调，前台地址
            notify_url=settings.NOTIFY_URL  # post回调，后台地址
        )
        return gateway + order_string

    def _before_create(self, attrs, user, pay_url, out_trade_no):
        attrs['user'] = user
        attrs['out_trade_no'] = out_trade_no
        self.context['pay_url'] = pay_url

    def validate(self, attrs):
        sum_price = self._check_price(attrs)
        out_trade_no = self._get_out_trade_no()
        user = self._get_user()
        pay_url = self._get_pay_url(sum_price, out_trade_no, attrs.get('subject'))
        self._before_create(attrs, user, pay_url, out_trade_no)
        return attrs

    def create(self, validated_data):
        course_list = validated_data.pop('course')
        order = models.Order.objects.create(**validated_data)
        for course in course_list:
            models.OrderDetail.objects.create(order=order, course=course, price=course.price, real_price=course.price)
        return order
